package me.zhengjie.modules.hanzi.service;

import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.hanzi.config.AiServiceProperties.AiProviderConfig;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.Base64;

/**
 * 统一的AI HTTP客户端
 * 支持不同API格式的HTTP请求
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class AiHttpClient {
    
    private final RestTemplate restTemplate;
    private final AiApiPathBuilder apiPathBuilder;
    
    /**
     * 发送聊天请求（文本模式）
     * @param config AI服务配置
     * @param prompt 提示词
     * @return AI响应
     */
    public String sendChatRequest(AiProviderConfig config, String prompt) {
        return sendChatRequest(config, prompt, null);
    }
    
    /**
     * 发送聊天请求（支持图片）
     * @param config AI服务配置
     * @param prompt 提示词
     * @param imageFile 图片文件（可选）
     * @return AI响应
     */
    public String sendChatRequest(AiProviderConfig config, String prompt, MultipartFile imageFile) {
        try {
            String apiType = config.getApiType();
            String chatPath = apiPathBuilder.buildChatCompletionsPath(config);
            String url = apiPathBuilder.buildFullUrl(config.getBaseUrl(), chatPath);
            
            log.info("发送{}格式AI请求到: {}", apiType, url);
            
            Object requestBody;
            switch (apiType.toLowerCase()) {
                case "gemini":
                    requestBody = buildGeminiRequest(config, prompt, imageFile);
                    break;
                case "openai":
                case "hf":
                default:
                    requestBody = buildOpenAiRequest(config, prompt, imageFile);
                    break;
            }
            
            HttpHeaders headers = buildHeaders(config);
            HttpEntity<Object> request = new HttpEntity<>(requestBody, headers);
            
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            
            if (response.getStatusCode() == HttpStatus.OK) {
                return extractResponseContent(response.getBody(), apiType);
            } else {
                log.error("AI请求失败，状态码: {}, 响应: {}", response.getStatusCode(), response.getBody());
                return null;
            }
            
        } catch (Exception e) {
            log.error("发送AI请求时发生错误", e);
            return null;
        }
    }
    
    /**
     * 构建Gemini格式的请求体
     */
    private Map<String, Object> buildGeminiRequest(AiProviderConfig config, String prompt, MultipartFile imageFile) throws IOException {
        Map<String, Object> request = new HashMap<>();
        
        // 构建contents数组
        List<Map<String, Object>> contents = new ArrayList<>();
        Map<String, Object> content = new HashMap<>();
        content.put("role", "user");
        
        List<Map<String, Object>> parts = new ArrayList<>();
        
        // 添加文本部分
        Map<String, Object> textPart = new HashMap<>();
        textPart.put("text", prompt);
        parts.add(textPart);
        
        // 如果有图片且支持图片输入，添加图片部分
        if (imageFile != null && config.isUseImageInput()) {
            Map<String, Object> imagePart = new HashMap<>();
            Map<String, Object> inlineData = new HashMap<>();
            inlineData.put("mimeType", imageFile.getContentType());
            inlineData.put("data", Base64.getEncoder().encodeToString(imageFile.getBytes()));
            imagePart.put("inlineData", inlineData);
            parts.add(imagePart);
        }
        
        content.put("parts", parts);
        contents.add(content);
        request.put("contents", contents);
        
        // 添加生成配置
        Map<String, Object> generationConfig = new HashMap<>();
        generationConfig.put("temperature", config.getTemperature());
        generationConfig.put("maxOutputTokens", config.getMaxTokens());
        request.put("generationConfig", generationConfig);
        
        return request;
    }
    
    /**
     * 构建OpenAI格式的请求体
     */
    private Map<String, Object> buildOpenAiRequest(AiProviderConfig config, String prompt, MultipartFile imageFile) throws IOException {
        Map<String, Object> request = new HashMap<>();
        request.put("model", config.getModel());
        request.put("temperature", config.getTemperature());
        request.put("max_tokens", config.getMaxTokens());
        
        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> message = new HashMap<>();
        message.put("role", "user");
        
        // 如果有图片且支持图片输入，使用多模态格式
        if (imageFile != null && config.isUseImageInput()) {
            List<Map<String, Object>> content = new ArrayList<>();
            
            // 文本部分
            Map<String, Object> textContent = new HashMap<>();
            textContent.put("type", "text");
            textContent.put("text", prompt);
            content.add(textContent);
            
            // 图片部分
            Map<String, Object> imageContent = new HashMap<>();
            imageContent.put("type", "image_url");
            Map<String, Object> imageUrl = new HashMap<>();
            String base64Image = "data:" + imageFile.getContentType() + ";base64," + 
                                Base64.getEncoder().encodeToString(imageFile.getBytes());
            imageUrl.put("url", base64Image);
            imageContent.put("image_url", imageUrl);
            content.add(imageContent);
            
            message.put("content", content);
        } else {
            // 纯文本格式
            message.put("content", prompt);
        }
        
        messages.add(message);
        request.put("messages", messages);
        
        return request;
    }
    
    /**
     * 构建请求头
     */
    private HttpHeaders buildHeaders(AiProviderConfig config) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        String apiType = config.getApiType();
        switch (apiType.toLowerCase()) {
            case "gemini":
                // Gemini使用API Key作为查询参数或头部
                headers.set("x-goog-api-key", config.getApiKey());
                break;
            case "openai":
            case "hf":
            default:
                // OpenAI格式使用Bearer Token
                headers.set("Authorization", "Bearer " + config.getApiKey());
                break;
        }
        
        return headers;
    }
    
    /**
     * 从响应中提取内容
     */
    private String extractResponseContent(String responseBody, String apiType) {
        try {
            switch (apiType.toLowerCase()) {
                case "gemini":
                    return extractGeminiContent(responseBody);
                case "openai":
                case "hf":
                default:
                    return extractOpenAiContent(responseBody);
            }
        } catch (Exception e) {
            log.error("提取AI响应内容失败", e);
            return responseBody; // 返回原始响应作为后备
        }
    }
    
    /**
     * 提取Gemini响应内容
     */
    @SuppressWarnings("unchecked")
    private String extractGeminiContent(String responseBody) {
        Map<String, Object> response = JSON.parseObject(responseBody, Map.class);
        List<Map<String, Object>> candidates = (List<Map<String, Object>>) response.get("candidates");
        
        if (candidates != null && !candidates.isEmpty()) {
            Map<String, Object> firstCandidate = candidates.get(0);
            Map<String, Object> content = (Map<String, Object>) firstCandidate.get("content");
            
            if (content != null) {
                List<Map<String, Object>> parts = (List<Map<String, Object>>) content.get("parts");
                if (parts != null && !parts.isEmpty()) {
                    return (String) parts.get(0).get("text");
                }
            }
        }
        
        return responseBody;
    }
    
    /**
     * 提取OpenAI响应内容
     */
    @SuppressWarnings("unchecked")
    private String extractOpenAiContent(String responseBody) {
        Map<String, Object> response = JSON.parseObject(responseBody, Map.class);
        List<Map<String, Object>> choices = (List<Map<String, Object>>) response.get("choices");
        
        if (choices != null && !choices.isEmpty()) {
            Map<String, Object> firstChoice = choices.get(0);
            Map<String, Object> message = (Map<String, Object>) firstChoice.get("message");
            
            if (message != null) {
                return (String) message.get("content");
            }
        }
        
        return responseBody;
    }
}